package com.breeze.components.core.util.id;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

/**
 * @author breeze
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class IdAssembler {

  public static <T, R> Set<R> assembleIdSet(Collection<T> list, Function<T, R> getId) {
    return list.stream().map(getId).collect(Collectors.toSet());
  }

  public static <T, R> List<R> assembleIdList(List<T> list, Function<T, R> getId) {
    return list.stream().map(getId).collect(Collectors.toList());
  }

  /** 组装获取id，过滤空对象及组装后null id 的list */
  public static <T, R> List<R> assembleIdListFilterNull(List<T> collect, Function<T, R> getId) {
    return collect.stream()
        .filter(Objects::nonNull)
        .map(getId)
        .filter(Objects::nonNull)
        .collect(Collectors.toList());
  }

  /** 1,2,3 [1,2,3] ,1,2,3, [1,2,3] */
  public static Set<Integer> assembleStrIdList(String sourceStr, String split) {
    if (StrUtil.isEmpty(sourceStr)) {
      return Collections.emptySet();
    }
    return StrUtil.split(sourceStr, split).stream()
        .filter(NumberUtil::isNumber)
        .map(Integer::valueOf)
        .collect(Collectors.toSet());
  }

  public static Set<Long> assembleStrIdLongList(String sourceStr, String split) {
    if (StrUtil.isEmpty(sourceStr)) {
      return Collections.emptySet();
    }
    return StrUtil.split(sourceStr, split).stream()
        .filter(NumberUtil::isNumber)
        .map(Long::valueOf)
        .collect(Collectors.toSet());
  }

  /** 1,2,3 -> ,1,2,3, ,1,2,3, -> ,1,2,3, */
  public static String assembleStrIdsLike(String source, String split) {
    return assembleIdListStr(assembleStrIdList(source, split), split, Function.identity(), true);
  }

  /** [1,2,3,3] , -> 1,2,3,3 [] -> '' */
  public static <T, R> String assembleIdListStr(
      Collection<T> collection, String join, Function<T, R> getIdStr) {
    return assembleIdListStr(collection, join, getIdStr, false);
  }

  /** false @see assembleIdListStr true [1,2,3,3] , -> ,1,2,3,3, */
  public static <T, R> String assembleIdListStr(
      Collection<T> collection, String join, Function<T, R> getIdStr, boolean addJoin) {
    if (CollUtil.isEmpty(collection)) {
      return StrUtil.EMPTY;
    }
    String joined =
        collection.stream().map(getIdStr).map(String::valueOf).collect(Collectors.joining(join));
    return addJoin ? String.format("%s%s%s", join, joined, join) : joined;
  }

  public static <T> String assembleIdListStrSingle(T obj, String join) {
    return assembleIdListStr(Collections.singletonList(obj), join, Objects::toString, true);
  }

  public static <T> String assembleIdsNames(
      String agreementTalentIds,
      String comma,
      Map<Integer, T> talentMap,
      Function<T, String> getName) {
    return IdAssembler.assembleStrIdList(agreementTalentIds, comma).stream()
        .map(talentMap::get)
        .map(getName)
        .collect(Collectors.joining(comma));
  }

  public static <T> Set<T> asssembleSet(List<T> rewardList) {
    return new HashSet<>(rewardList);
  }
}
